package dingding

import (
	"context"

	"github.com/emicklei/go-restful/v3"
	"github.com/infraboard/mcube/client/rest"
	"github.com/infraboard/mcube/logger"
	"github.com/infraboard/mcube/logger/zap"
)

func NewDingDingClient(conf *Config) *DingDing {
	client := rest.NewRESTClient()
	client.SetBaseURL("https://api.dingtalk.com")
	return &DingDing{
		Config: conf,
		rc:     client,
		log:    zap.L().Named("auth.dingding"),
	}
}

// 需要跟钉钉交互:
// 官方sdk：
// 直接根据API文档，封装直接的sdk (选择自己封装)
type DingDing struct {
	*Config
	rc  *rest.RESTClient
	tk  *DingDingAccessToken
	log logger.Logger
}

// 获取用户Token https://open.dingtalk.com/document/orgapp-server/obtain-user-token?spm=ding_open_doc.document.0.0.5cf7722fu9sqAm#doc-api-dingtalk-GetUserToken
func (d *DingDing) Login(ctx context.Context, code string) error {
	req := &GetUserTokenRequest{
		ClientId:     d.ClientId,
		ClientSecret: d.ClientSecret,
		Code:         code,
		GrantType:    "authorization_code",
	}
	tk := NewDingDingAccessToken()

	err := d.rc.
		Post("/v1.0/oauth2/userAccessToken").
		Header(restful.HEADER_ContentType, restful.MIME_JSON).
		Body(req).
		Do(ctx).
		Into(tk)
	if err != nil {
		return err
	}

	// 登录成功后客户端缓存Token
	d.tk = tk
	d.log.Debugf("login tk: %s", tk.AccessToken)
	return nil
}

// 查询用户身份 https://open.dingtalk.com/document/orgapp-server/dingtalk-retrieve-user-information?spm=ding_open_doc.document.0.0.5cf7722fu9sqAm#doc-api-dingtalk-GetUser
func (d *DingDing) GetUserInfo(ctx context.Context) (*User, error) {
	u := NewUser()
	err := d.rc.Get("/v1.0/contact/users/me").
		Header("x-acs-dingtalk-access-token", d.tk.AccessToken).
		Header(restful.HEADER_ContentType, restful.MIME_JSON).
		Do(ctx).
		Into(u)
	if err != nil {
		return nil, err
	}
	return u, nil
}
